#include "common.h"
#include "level.h"
#include "playstate.h"

#include "debugdialog.h"
#include <commctrl.h>

#include "mapform.h"

static MapForm* g_pMapForm = NULL;
static COLORREF color[4] = 
{
	RGB( 255, 0, 0 ),
	RGB( 255, 255, 0 ),
	RGB( 255, 0, 255 ),
	RGB( 0, 0, 255 ),
};

LRESULT CALLBACK MapFormProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam )
{
	switch( msg )
	{
	case WM_COMMAND :
		if( (HWND)lParam == GetDlgItem( g_pMapForm->GetWindowHandle(), IDC_RELOADBUTTON ) )
		{
			PlayState* pState = dynamic_cast< PlayState* >( Core::GetInstance().GetGameState() );
			if( pState )
			{
				pState->ReloadLevel( 0 );
				InvalidateRect( g_pMapForm->GetWindowHandle(), NULL, TRUE );
			}
		}
		break;
	case WM_PAINT :
		g_pMapForm->DrawMap( 0 );
		break;
	}
	return false;
}

MapForm::MapForm( int id, HWND hParent )
:	_hMapFrame( NULL )
,	_hParent( hParent )
,	_hWnd( NULL )
,	_id( id )
,	_nGrid( 0 )
{
	g_pMapForm = this;
	memset( _pMap, 0, sizeof( BYTE* )*6 );

	Core& core = Core::GetInstance();
	_hWnd = CreateDialog(
		core.GetInstanceHandle(),
		MAKEINTRESOURCE( IDD_MAPFORM ),
		_hParent,
		( DLGPROC )MapFormProc );

	RECT rc;
	GetClientRect( _hWnd, &rc );
	SetWindowPos( _hWnd, HWND_TOP, 2, 22, rc.right, rc.bottom, 0 ); 

	// Main map frame
	_hMapFrame = GetDlgItem( _hWnd, IDC_MAINMAPFRAME );

	// Color frame
	_hBoxList.push_back( GetDlgItem( _hWnd, IDC_CORRECTPATHFRAME ) );
	_hBoxList.push_back( GetDlgItem( _hWnd, IDC_BRANCHPATHFRAME ) );
	_hBoxList.push_back( GetDlgItem( _hWnd, IDC_STARTPOSFRAME ) );
	_hBoxList.push_back( GetDlgItem( _hWnd, IDC_ENDPOSFRAME ) );

	// Reload button

}

MapForm::~MapForm()
{
};

void MapForm::DrawMap( BYTE flag )
{
	if( _nGrid == 0 )
	{
		return;
	}

	RECT dlgRC, frameRC;
	GetWindowRect( _hWnd, &dlgRC );
	GetWindowRect( _hMapFrame, &frameRC );

	Point pos( frameRC.left-dlgRC.left, frameRC.top-dlgRC.top );
	Point size( frameRC.right-frameRC.left, frameRC.bottom-frameRC.top );
	float dx = size.x / static_cast< float >( _nGrid );
	float dy = size.y / static_cast< float >( _nGrid );

	PAINTSTRUCT ps;
	HDC hdc = BeginPaint( _hWnd, &ps );
	
	// draw path
	if( _pMap[0] != NULL )
	{
		for( int y = 0; y < _nGrid; ++y )
		{
			for(int x = 0; x < _nGrid; ++x )
			{
				if( _pMap[0][y*_nGrid+x] <= 0 )
				{
					DrawSquare( hdc, Point( x, y ), pos, dx, dy );
				}
			}
		}
	}

	// draw path
	for(  int y = 0; y < _nGrid; ++y )
	{
		for(int x = 0; x < _nGrid; ++x )
		{
			if( _pMap[0][y*_nGrid+x] <= 0 )
			{
				DrawSquare( hdc, Point( x, y ), pos, dx, dy );
			}
		}
	}

	// Draw horizonal lines
	for( int i = 1; i < _nGrid; ++i )
	{
		MoveToEx( hdc, pos.x+(int)(dx*i), pos.y, NULL );
		LineTo( hdc, pos.x+(int)(dx*i), pos.y+size.y );
	}
	// Draw vertical lines
	for( int i = 1; i < _nGrid; ++i )
	{
		MoveToEx( hdc, pos.x, pos.y+(int)(dy*i), NULL );
		LineTo( hdc, pos.x+size.x, pos.y+(int)(dy*i) );
	}
	EndPaint( _hWnd, &ps );

	for( int i = 0; i < (int)_hBoxList.size(); ++i )
	{
		if( _hBoxList[i] == NULL )
		{
			continue;
		}
		RECT rc;
		GetClientRect( _hBoxList[i], &rc );
		hdc = BeginPaint( _hBoxList[i], &ps );
		HBRUSH hBrush, oldBrush;
		hBrush = CreateSolidBrush( color[i] );
		oldBrush = (HBRUSH)SelectObject( hdc, hBrush );

		FillRect( hdc, &rc, hBrush );

		SelectObject( hdc, oldBrush );
		DeleteObject( hBrush );
		EndPaint( _hBoxList[i], &ps );
	}
}

void MapForm::SetMap( char** ppMap, int nGrid )
{
	_nGrid = nGrid;
	for( int i = 0; i < 6; ++i )
	{
		_pMap[i] = ppMap[i];
	}
}

void MapForm::DrawSquare( HDC hdc, const Point& index, const Point& offset, float dx, float dy )
{
	RECT rc;
	rc.left = static_cast< int >( dx*index.x ) + offset.x;
	rc.right = static_cast< int >( dx*(index.x+1) ) + offset.x + 1;
	rc.top = static_cast< int >( dy*(_nGrid-index.y) ) + offset.y;
	rc.bottom = static_cast< int >( dy*(_nGrid-index.y-1) ) + offset.y + 1;

	HBRUSH hBrush, oldBrush;
	hBrush = CreateSolidBrush( color[ -1*_pMap[0][(index.y*_nGrid)+index.x]-1 ] );
	oldBrush = (HBRUSH)SelectObject( hdc, hBrush );

	FillRect( hdc, &rc, hBrush );

	SelectObject( hdc, oldBrush );
	DeleteObject( hBrush );
}